The Cluster Bomb modification turned out to be a very interesting project.  It did not turn out the way it was originally envisioned.  Whether this was due to a limitation of the BZ2 ODF definition system, or merely my limited knowledge about how to use it, compromises had to be made.  However, the final result is reasonably close to the vision.

Furthermore, while most other weapon mods are relatively simple modifications of existing ODF files, the Cluster Bomb turned out to be an amalgam of at least three different BZ2 weapons.


apcluster.odf
-------------
At the top of the ODF hierarchy for this weapon is the power-up ODF, apcluster.odf.  Here we define the requirements for construction, should this power-up be used in a mission featuring and appropriately modified Armory.  Both a Factory and an Armory would be required.  Most of the remaining parameters define the power-up cube to be displayed.  

The critical parameter for our purposes is weaponName, which identifies the weapon ODF, the next file down in the hierarchy.

[GameObjectClass]
geometryName = "apmort00.xsi"
classLabel = "wpnpower"
scrapCost = 30
scrapValue = 0
maxHealth = 1500
maxAmmo = 0
unitName = NULL
aiName = "PowerUpProcess"

requireCount = 2
requireName1 = "ibfact"
requireText1 = "Build Factory"
requireName2 = "ibarmo"
requireText2 = "Build Armory"

lightHard1 = "hp_light_1"
lightName1 = "omnibrown"

[PowerUpClass]
soundPickup = "pickup01.wav"
soundReject = "reject.wav"

[WeaponPowerupClass]
weaponName = "gcluster"


gcluster.odf
------------
Here we start defining the weapon itself.  The classLabel and wpnCategory parameters define it as mortar, so it will fill a mortar hardpoint in a vehicle.  The wpnName specifies the text to be displayed in the game's weapon load-out list.

The aiRange parameter determines the perimeter within which an AI unit will beginning firing this weapon on an enemy vehicle or building.  The shotDelay parameter determines how quickly the weapon can be fired.  In this case, it's quite a bit lower than other mortars.

In my original vision, I had hoped to create a mortar weapon that would deliver a shell into the air where it would burst into several separate bomblets which would then descend to the ground and thereupon burst with spectacular effect.  I was unable to get the airburst to work the way I wanted, so the compromise was to decrease the shotDelay to such a point that several mortar rounds could be delivered and yield the ground explosion effect desired.

The ordName parameter is critical.  It identifies the ordnance ODF, the next file in the heirarchy.

[WeaponClass]
classLabel = "mortar"
ordName = "clusterbm"
wpnName = "Cluster Bomb"
fireSound = "smort01.wav"
wpnReticle = "gsplint"
wpnLadder = "gsplint.L0"
wpnPriority = 4
wpnCategory = "MORT"
aiRange = 150

[CannonClass]
shotDelay = 0.3


clusterbm.odf
-------------
Now the weapon definition starts to get complicated.  This ODF primarily describes how the mortar shot will be rendered.  However, because we are specifying a classLabel of sparybomb, we will have to provide other ODF files to describe how the payload will be rendered when the mortar detonates.

Everything here is pretty much the same as what you would find for the Splinter Mortar.  Note the SprayBombClass section.  It is there that we define the payloadName, a critical parameter which identifies the next ODF file in the hierarchy.

Note also that the spraybomb itself does no damage.

[OrdnanceClass]
classLabel = "spraybomb"
shotGeometry = "ioartl00.xsi"
shotSound = "baz03.wav"
xplGround = NULL
xplVehicle = NULL
xplBuilding = NULL
rendername = "clusterbm.render"

ammoCost = 100
lifeSpan = 1e30
shotSpeed = 45.0

damageValue(N) = 0
damageValue(L) = 0
damageValue(H) = 0
damageValue(S) = 0
damageValue(D) = 0
damageValue(A) = 0

[SprayBombClass]
payloadName = "clusterx"

[Render]
renderBase = "draw_twirl_trail"
textureName = "smoke.tga"
textureBlend = "srcalpha invsrcalpha modulatealpha"
startColor = "127 159 159 63"
finishColor = "0 0 191 0"
startRadius = 0.3
finishRadius = 1.0
animateTime = 2.0
emitDelay = 0.01
emitVelocity = "0.0 0.0 0.0"
emitVariance = "1.0 1.0 1.0"
emitLife = 2.0


clusterx.odf
------------
This is a relatively small ODF file in the chain.  It's purpose is to begin the definition of how the spraybomb payload is to be rendered.  Look closely and you'll see that this looks suspiciously like the definition for the Fountain Mine.  In fact, I probably should have change the unitName paramter!

The critical parameters here are lifeSpan, shotDelay, shotVariance and payloadName.  A short lifeSpan is specified because we don't need this thing to hang around for very long.  The shotDelay is extremely short because we want the payload shots to spray virtually all at the same time.  The shotVariance determines how well the payload shots will spread from the delivery point.  If this number is too low, the shots will all go almost straight up.  We want them spray out at a lower angle so they'll have some chance of hitting targets around them.  

The payloadName (another one!) is critical.  This identifies the next ODF file in the hierarchy.  Note that there is a second ODF file further down in the hierarchy.  The explosionName parameter identifies a special ODF file describing the explosion of the cluster bomb mine.

[GameObjectClass]
geometryName = "gmflar00.x"
classLabel = "flare"
scrapCost = 0
scrapValue = 0
maxHealth = 400
maxAmmo = 200
unitName = "Fountain"
heatSignature = 0.0
explosionName = "xclstxpl"

[MineClass]
lifeSpan = 0.7

[FlareMineClass]
payloadName = "sprayshot"
fireSound = "gflas00.wav"
triggerDelay = 0.5
shotDelay = 0.01
shotVariance = 60.0


xclstxpl.odf
------------
The primary purpose of this ODF is to specify how the Cluster Bomb explosion is to be rendered.  Not the for spray bomb payload shots, but for the spray bomb itself.

Note that the spray bomb explosion delivers a significant amount of damage, but only to targets within a very close range.  In fact, the largest portion of the damage is delivered in the spray bomb shots.  So, to be really effective against other vehicles, you'll have to get the Cluster Bomb in close, underneath them if possible.

The rendering has been adjusted to display an orange explosion that roughly matches the damage radius.

// ==============
// CLUSTER BOMB EXPLOSION
// ==============

[ExplosionClass]
classLabel = "explosion"

particleTypes = 2
particleClass1 = "xclstxpl.core"
particleCount1 = 1
particleVeloc1 = "0.0 0.0 0.0"
particleClass2 = "xclstxpl.puff"
particleCount2 = 70
particleVeloc2 = "90.0 90.0 90.0"

explSound = "xmv1.wav"
damageRadius = 20.0
damageValue(N) = 150
damageValue(L) = 100
damageValue(H) = 75
damageValue(S) = 150
damageValue(D) = 100
damageValue(A) = 75

[Core]
simulateBase = "sim_null"
lifeTime = 1.0
renderBase = "draw_twirl"
textureName = "flame.tga"
textureBlend = "one one modulate"
startColor = "159 159 63 255"
finishColor = "159 0 0 0"
startRadius = 5.0
finishRadius = 20.0
animateTime = 1.0

[Puff]
simulateBase = "sim_smoke"
lifeTime = 1.0
renderBase = "draw_twirl"
textureName = "flame.tga"
textureBlend = "one one modulate"
startColor = "159 159 63 255"
finishColor = "159 0 0 0"
startRadius = 10.0
finishRadius = 1.0
animateTime = 1.0


sprayshot.odf
-------------
Finally, we get down to the rendering of the ultimate payload of the original Cluster Bomb mortar shot.  If you look closely, you'll see that this final ODF very closely resembles the Bazooka ordnance.  In fact, it references the basooka explosion ODFs!  By that means I avoid having to create new explosion ODFs for the modified weapon.

It is here that we specify inflicted damage by armor and shield types.  Note the lifeSpan and especially the shotSpeed parameters.  These shots are meant to rocket out of the spraybomb at a very high rate of speed!  Everything else is pretty much the same as for the Bazooka shot rendering.

[OrdnanceClass]
classLabel = "bullet"
shotGeometry = NULL
shotSound = "igtow04.wav"
renderName = "sprayshot.render"

xplGround = "xsbazgnd_c"
xplVehicle = "xsbazcar_c"
xplBuilding = "xsbazcar_c"

ammoCost = 0
lifeSpan = 1.0
shotSpeed = 250.0

damageValue(N) = 600 // none
damageValue(L) = 450 // light
damageValue(H) = 300 // heavy

damageValue(S) = 600 // standard
damageValue(D) = 450 // deflection
damageValue(A) = 300 // absorbtion

[Render]
renderBase = "draw_multi"
renderCount = 3
renderName1 = "sprayshot.flare"
renderName2 = "sprayshot.halo"
renderName3 = "sprayshot.trail"

[Flare]
renderBase = "draw_sprite"
textureName = "lightflare.tga"
textureBlend = "one one modulate"
startColor = "255 255 255 63"
finishColor = "255 255 255 63"
startRadius = 0.5
finishRadius = 0.5

[Halo]
renderBase = "draw_sprite"
textureName = "lighthalo.tga"
textureBlend = "one one modulate"
startColor = "63 191 255 127"
finishColor = "63 191 255 127"
startRadius = 0.5
finishRadius = 0.5

[Trail]
renderBase = "draw_trail"
textureName = "trail2.tga"
textureBlend = "one one modulate"
startColor = "191 191 255 50"
finishColor = "191 191 191 0"
startRadius = 0.4
finishRadius = 1.2
segmentTime = 0.3


This little project did take some time and quite a bit of experimentation to get a final weapon design that worked fairly well, and not too differently from the original conception.  The descriptions of several different weapons were drawn upon including Splinter Mortar, Fountain Mine and Bazooka.  What a monster!

If I were to continue to tinker with this thing, or work to produce another similar weapon, I might take another look at the shotVariance parameter in the clusterx.odf or examine how similar effects are achieved in the definition of Da Bomb, which is actually defined as a mine.

Many possible variations come to mind!

Here's a complete list of the ODF files need for the Cluster Bomb:
apcluster.odf
gcluster.odf
clusterbm.odf
clusterx.odf
xclstxpl.odf
sprayshot.odf
xsbazgnd_c.odf  (not custom)
xsbazcar_c.odf  (not custom)
